home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / utilit~1 / futilsrc.zoo / fileutil / lib / getdate.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-20  |  45.4 KB  |  1,702 lines

  1.  
  2. /*  A Bison parser, made from getdate.y  */
  3.  
  4. #define    tAGO    258
  5. #define    tDAY    259
  6. #define    tDAYZONE    260
  7. #define    tID    261
  8. #define    tMERIDIAN    262
  9. #define    tMINUTE_UNIT    263
  10. #define    tMONTH    264
  11. #define    tMONTH_UNIT    265
  12. #define    tSEC_UNIT    266
  13. #define    tSNUMBER    267
  14. #define    tUNUMBER    268
  15. #define    tZONE    269
  16. #define    tDST    270
  17.  
  18. #line 1 "getdate.y"
  19.  
  20. /* $Revision: 2.1 $
  21. **
  22. **  Originally written by Steven M. Bellovin <smb@research.att.com> while
  23. **  at the University of North Carolina at Chapel Hill.  Later tweaked by
  24. **  a couple of people on Usenet.  Completely overhauled by Rich $alz
  25. **  <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
  26. **  send any email to Rich.
  27. **
  28. **  This grammar has eight shift/reduce conflicts.
  29. **
  30. **  This code is in the public domain and has no copyright.
  31. */
  32. /* SUPPRESS 287 on yaccpar_sccsid *//* Unusd static variable */
  33. /* SUPPRESS 288 on yyerrlab *//* Label unused */
  34.  
  35. #ifdef __GNUC__
  36. #define alloca __builtin_alloca
  37. #else
  38. #ifdef sparc
  39. #include <alloca.h>
  40. #else
  41. #ifdef _AIX /* for Bison */
  42.  #pragma alloca
  43. #else
  44. char *alloca ();
  45. #endif
  46. #endif
  47. #endif
  48.  
  49. #include <stdio.h>
  50. #include <ctype.h>
  51.  
  52. #if    defined(vms)
  53. #include <types.h>
  54. #include <time.h>
  55. #else
  56. #include <sys/types.h>
  57. #if    defined(USG) || defined(FTIME_MISSING)
  58. /*
  59. **  If you need to do a tzset() call to set the
  60. **  timezone, and don't have ftime().
  61. */
  62. struct timeb {
  63.     time_t        time;        /* Seconds since the epoch    */
  64.     unsigned short    millitm;    /* Field not used        */
  65.     short        timezone;
  66.     short        dstflag;    /* Field not used        */
  67. };
  68. #else
  69. #include <sys/timeb.h>
  70. #endif    /* defined(USG) || defined(FTIME_MISSING) */
  71. #if    defined(BSD4_2) || defined(BSD4_1C)
  72. #include <sys/time.h>
  73. #else
  74. #include <time.h>
  75. #endif    /* defined(BSD4_2) */
  76. #endif    /* defined(vms) */
  77.  
  78. #if defined (STDC_HEADERS) || defined (USG)
  79. #include <string.h>
  80. #endif
  81.  
  82. extern struct tm    *localtime();
  83.  
  84. #define yyparse getdate_yyparse
  85. #define yylex getdate_yylex
  86. #define yyerror getdate_yyerror
  87.  
  88. #if    !defined(lint) && !defined(SABER)
  89. static char RCS[] =
  90.     "$Header: str2date.y,v 2.1 90/09/06 08:15:06 cronan Exp $";
  91. #endif    /* !defined(lint) && !defined(SABER) */
  92.  
  93.  
  94. #define EPOCH        1970
  95. #define HOUR(x)        ((time_t)(x) * 60)
  96. #define SECSPERDAY    (24L * 60L * 60L)
  97.  
  98.  
  99. /*
  100. **  An entry in the lexical lookup table.
  101. */
  102. typedef struct _TABLE {
  103.     char    *name;
  104.     int        type;
  105.     time_t    value;
  106. } TABLE;
  107.  
  108.  
  109. /*
  110. **  Daylight-savings mode:  on, off, or not yet known.
  111. */
  112. typedef enum _DSTMODE {
  113.     DSTon, DSToff, DSTmaybe
  114. } DSTMODE;
  115.  
  116. /*
  117. **  Meridian:  am, pm, or 24-hour style.
  118. */
  119. typedef enum _MERIDIAN {
  120.     MERam, MERpm, MER24
  121. } MERIDIAN;
  122.  
  123.  
  124. /*
  125. **  Global variables.  We could get rid of most of these by using a good
  126. **  union as the yacc stack.  (This routine was originally written before
  127. **  yacc had the %union construct.)  Maybe someday; right now we only use
  128. **  the %union very rarely.
  129. */
  130. static char    *yyInput;
  131. static DSTMODE    yyDSTmode;
  132. static time_t    yyDayOrdinal;
  133. static time_t    yyDayNumber;
  134. static int    yyHaveDate;
  135. static int    yyHaveDay;
  136. static int    yyHaveRel;
  137. static int    yyHaveTime;
  138. static int    yyHaveZone;
  139. static time_t    yyTimezone;
  140. static time_t    yyDay;
  141. static time_t    yyHour;
  142. static time_t    yyMinutes;
  143. static time_t    yyMonth;
  144. static time_t    yySeconds;
  145. static time_t    yyYear;
  146. static MERIDIAN    yyMeridian;
  147. static time_t    yyRelMonth;
  148. static time_t    yyRelSeconds;
  149.  
  150.  
  151. #line 134 "getdate.y"
  152. typedef union {
  153.     time_t        Number;
  154.     enum _MERIDIAN    Meridian;
  155. } YYSTYPE;
  156.  
  157. #ifndef YYLTYPE
  158. typedef
  159.   struct yyltype
  160.     {
  161.       int timestamp;
  162.       int first_line;
  163.       int first_column;
  164.       int last_line;
  165.       int last_column;
  166.       char *text;
  167.    }
  168.   yyltype;
  169.  
  170. #define YYLTYPE yyltype
  171. #endif
  172.  
  173. #define    YYACCEPT    return(0)
  174. #define    YYABORT    return(1)
  175. #define    YYERROR    goto yyerrlab
  176. #include <stdio.h>
  177.  
  178. #ifndef __STDC__
  179. #define const
  180. #endif
  181.  
  182.  
  183.  
  184. #define    YYFINAL        49
  185. #define    YYFLAG        -32768
  186. #define    YYNTBASE    19
  187.  
  188. #define YYTRANSLATE(x) ((unsigned)(x) <= 270 ? yytranslate[x] : 29)
  189.  
  190. static const char yytranslate[] = {     0,
  191.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  192.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  193.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  194.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  195.      2,     2,     2,    17,     2,     2,    18,     2,     2,     2,
  196.      2,     2,     2,     2,     2,     2,     2,    16,     2,     2,
  197.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  198.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  199.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  200.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  201.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  202.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  203.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  204.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  205.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  206.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  207.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  208.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  209.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  210.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  211.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  212.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  213.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  214.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  215.      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
  216.      2,     2,     2,     2,     2,     1,     2,     3,     4,     5,
  217.      6,     7,     8,     9,    10,    11,    12,    13,    14,    15
  218. };
  219.  
  220. static const short yyrline[] = {     0,
  221.    148,   149,   152,   155,   158,   161,   164,   167,   170,   176,
  222.    182,   189,   195,   205,   209,   213,   220,   224,   228,   234,
  223.    238,   243,   247,   252,   256,   263,   267,   270,   273,   276,
  224.    279,   282,   285,   288,   291,   294,   299,   327,   330
  225. };
  226.  
  227. static const char * const yytname[] = {     0,
  228. "error","$illegal.","tAGO","tDAY","tDAYZONE","tID","tMERIDIAN","tMINUTE_UNIT","tMONTH","tMONTH_UNIT",
  229. "tSEC_UNIT","tSNUMBER","tUNUMBER","tZONE","tDST","':'","','","'/'","spec"
  230. };
  231.  
  232. static const short yyr1[] = {     0,
  233.     19,    19,    20,    20,    20,    20,    20,    20,    21,    21,
  234.     21,    21,    21,    22,    22,    22,    23,    23,    23,    24,
  235.     24,    24,    24,    24,    24,    25,    25,    26,    26,    26,
  236.     26,    26,    26,    26,    26,    26,    27,    28,    28
  237. };
  238.  
  239. static const short yyr2[] = {     0,
  240.      0,     2,     1,     1,     1,     1,     1,     1,     2,     4,
  241.      4,     6,     6,     1,     1,     2,     1,     2,     2,     3,
  242.      5,     2,     4,     2,     3,     2,     1,     2,     2,     1,
  243.      2,     2,     1,     2,     2,     1,     1,     0,     1
  244. };
  245.  
  246. static const short yydefact[] = {     1,
  247.      0,    17,    15,    30,     0,    36,    33,     0,    37,    14,
  248.      2,     3,     4,     6,     5,     7,    27,     8,    18,    22,
  249.     29,    34,    31,    19,     9,    28,    24,    35,    32,     0,
  250.      0,    16,    26,     0,    25,    38,    20,    23,    39,    11,
  251.      0,    10,     0,    38,    21,    13,    12,     0,     0
  252. };
  253.  
  254. static const short yydefgoto[] = {     1,
  255.     11,    12,    13,    14,    15,    16,    17,    18,    42
  256. };
  257.  
  258. static const short yypact[] = {-32768,
  259.      0,   -15,-32768,-32768,   -10,-32768,-32768,    23,    11,    -8,
  260. -32768,-32768,-32768,-32768,-32768,-32768,    13,-32768,-32768,     7,
  261. -32768,-32768,-32768,-32768,-32768,-32768,     4,-32768,-32768,    12,
  262.     17,-32768,-32768,    22,-32768,    16,     8,-32768,-32768,-32768,
  263.     24,-32768,    25,    -6,-32768,-32768,-32768,    36,-32768
  264. };
  265.  
  266. static const short yypgoto[] = {-32768,
  267. -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,    -5
  268. };
  269.  
  270.  
  271. #define    YYLAST        39
  272.  
  273.  
  274. static const short yytable[] = {    48,
  275.     39,    19,    20,     2,     3,    46,    32,     4,     5,     6,
  276.      7,     8,     9,    10,    24,    33,    35,    25,    26,    27,
  277.     28,    29,    39,    34,    36,    43,    30,    40,    31,    37,
  278.     21,    41,    22,    23,    38,    49,    44,    45,    47
  279. };
  280.  
  281. static const short yycheck[] = {     0,
  282.      7,    17,    13,     4,     5,    12,    15,     8,     9,    10,
  283.     11,    12,    13,    14,     4,     3,    13,     7,     8,     9,
  284.     10,    11,     7,    17,    13,    18,    16,    12,    18,    13,
  285.      8,    16,    10,    11,    13,     0,    13,    13,    44
  286. };
  287. #define YYPURE 1
  288.  
  289. #include <memory.h>
  290. #line 3 "bison.simple"
  291.  
  292. /* Skeleton output parser for bison,
  293.    copyright (C) 1984 Bob Corbett and Richard Stallman
  294.  
  295.                NO WARRANTY
  296.  
  297.   BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
  298. NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW.  EXCEPT
  299. WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
  300. RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
  301. WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
  302. BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  303. FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY
  304. AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE
  305. DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
  306. CORRECTION.
  307.  
  308.  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
  309. STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
  310. WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
  311. LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
  312. OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
  313. USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
  314. DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
  315. A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
  316. PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
  317. DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
  318.  
  319.         GENERAL PUBLIC LICENSE TO COPY
  320.  
  321.   1. You may copy and distribute verbatim copies of this source file
  322. as you receive it, in any medium, provided that you conspicuously and
  323. appropriately publish on each copy a valid copyright notice "Copyright
  324. (C) 1985 Free Software Foundation, Inc."; and include following the
  325. copyright notice a verbatim copy of the above disclaimer of warranty
  326. and of this License.  You may charge a distribution fee for the
  327. physical act of transferring a copy.
  328.  
  329.   2. You may modify your copy or copies of this source file or
  330. any portion of it, and copy and distribute such modifications under
  331. the terms of Paragraph 1 above, provided that you also do the following:
  332.  
  333.     a) cause the modified files to carry prominent notices stating
  334.     that you changed the files and the date of any change; and
  335.  
  336.     b) cause the whole of any work that you distribute or publish,
  337.     that in whole or in part contains or is a derivative of this
  338.     program or any part thereof, to be licensed at no charge to all
  339.     third parties on terms identical to those contained in this
  340.     License Agreement (except that you may choose to grant more extensive
  341.     warranty protection to some or all third parties, at your option).
  342.  
  343.     c) You may charge a distribution fee for the physical act of
  344.     transferring a copy, and you may at your option offer warranty
  345.     protection in exchange for a fee.
  346.  
  347. Mere aggregation of another unrelated program with this program (or its
  348. derivative) on a volume of a storage or distribution medium does not bring
  349. the other program under the scope of these terms.
  350.  
  351.   3. You may copy and distribute this program (or a portion or derivative
  352. of it, under Paragraph 2) in object code or executable form under the terms
  353. of Paragraphs 1 and 2 above provided that you also do one of the following:
  354.  
  355.     a) accompany it with the complete corresponding machine-readable
  356.     source code, which must be distributed under the terms of
  357.     Paragraphs 1 and 2 above; or,
  358.  
  359.     b) accompany it with a written offer, valid for at least three
  360.     years, to give any third party free (except for a nominal
  361.     shipping charge) a complete machine-readable copy of the
  362.     corresponding source code, to be distributed under the terms of
  363.     Paragraphs 1 and 2 above; or,
  364.  
  365.     c) accompany it with the information you received as to where the
  366.     corresponding source code may be obtained.  (This alternative is
  367.     allowed only for noncommercial distribution and only if you
  368.     received the program in object code or executable form alone.)
  369.  
  370. For an executable file, complete source code means all the source code for
  371. all modules it contains; but, as a special exception, it need not include
  372. source code for modules which are standard libraries that accompany the
  373. operating system on which the executable file runs.
  374.  
  375.   4. You may not copy, sublicense, distribute or transfer this program
  376. except as expressly provided under this License Agreement.  Any attempt
  377. otherwise to copy, sublicense, distribute or transfer this program is void and
  378. your rights to use the program under this License agreement shall be
  379. automatically terminated.  However, parties who have received computer
  380. software programs from you with this License Agreement will not have
  381. their licenses terminated so long as such parties remain in full compliance.
  382.  
  383.   5. If you wish to incorporate parts of this program into other free
  384. programs whose distribution conditions are different, write to the Free
  385. Software Foundation at 675 Mass Ave, Cambridge, MA 02139.  We have not yet
  386. worked out a simple rule that can be stated here, but we will often permit
  387. this.  We will be guided by the two goals of preserving the free status of
  388. all derivatives of our free software and of promoting the sharing and reuse of
  389. software.
  390.  
  391.  
  392. In other words, you are welcome to use, share and improve this program.
  393. You are forbidden to forbid anyone else to use, share and improve
  394. what you give them.   Help stamp out software-hoarding!  */
  395.  
  396. /* This is the parser code that is written into each bison parser
  397.   when the %semantic_parser declaration is not specified in the grammar.
  398.   It was written by Richard Stallman by simplifying the hairy parser
  399.   used when %semantic_parser is specified.  */
  400.  
  401. /* Note: there must be only one dollar sign in this file.
  402.    It is replaced by the list of actions, each action
  403.    as one case of the switch.  */
  404.  
  405. #define yyerrok        (yyerrstatus = 0)
  406. #define yyclearin    (yychar = YYEMPTY)
  407. #define YYEMPTY        -2
  408. #define YYEOF        0
  409. #define YYFAIL        goto yyerrlab;
  410.  
  411. #define YYTERROR    1
  412.  
  413. #ifndef YYIMPURE
  414. #define YYLEX        yylex()
  415. #endif
  416.  
  417. #ifndef YYPURE
  418. #define YYLEX        yylex(&yylval, &yylloc)
  419. #endif
  420.  
  421. /* If nonreentrant, generate the variables here */
  422.  
  423. #ifndef YYIMPURE
  424.  
  425. int    yychar;            /*  the lookahead symbol        */
  426. YYSTYPE    yylval;            /*  the semantic value of the        */
  427.                 /*  lookahead symbol            */
  428.  
  429. YYLTYPE yylloc;            /*  location data for the lookahead    */
  430.                 /*  symbol                */
  431.  
  432. int yynerr;            /*  number of parse errors so far       */
  433.  
  434. #ifdef YYDEBUG
  435. int yydebug = 0;        /*  nonzero means print parse trace    */
  436. #endif
  437.  
  438. #endif  /* YYIMPURE */
  439.  
  440.  
  441. /*  YYMAXDEPTH indicates the initial size of the parser's stacks    */
  442.  
  443. #ifndef    YYMAXDEPTH
  444. #define YYMAXDEPTH 200
  445. #endif
  446.  
  447. /*  YYMAXLIMIT is the maximum size the stacks can grow to
  448.     (effective only if the built-in stack extension method is used).  */
  449.  
  450. #ifndef YYMAXLIMIT
  451. #define YYMAXLIMIT 10000
  452. #endif
  453.  
  454.  
  455. #line 168 "bison.simple"
  456. int
  457. yyparse()
  458. {
  459.   register int yystate;
  460.   register int yyn;
  461.   register short *yyssp;
  462.   register YYSTYPE *yyvsp;
  463.   YYLTYPE *yylsp;
  464.   int yyerrstatus;    /*  number of tokens to shift before error messages enabled */
  465.   int yychar1;        /*  lookahead token as an internal (translated) token number */
  466.  
  467.   short    yyssa[YYMAXDEPTH];    /*  the state stack            */
  468.   YYSTYPE yyvsa[YYMAXDEPTH];    /*  the semantic value stack        */
  469.   YYLTYPE yylsa[YYMAXDEPTH];    /*  the location stack            */
  470.  
  471.   short *yyss = yyssa;        /*  refer to the stacks thru separate pointers */
  472.   YYSTYPE *yyvs = yyvsa;    /*  to allow yyoverflow to reallocate them elsewhere */
  473.   YYLTYPE *yyls = yylsa;
  474.  
  475.   int yymaxdepth = YYMAXDEPTH;
  476.  
  477. #ifndef YYPURE
  478.   int yychar;
  479.   YYSTYPE yylval;
  480.   YYLTYPE yylloc;
  481. #endif
  482.  
  483. #ifdef YYDEBUG
  484.   extern int yydebug;
  485. #endif
  486.  
  487.  
  488.   YYSTYPE yyval;        /*  the variable used to return        */
  489.                 /*  semantic values from the action    */
  490.                 /*  routines                */
  491.  
  492.   int yylen;
  493.  
  494. #ifdef YYDEBUG
  495.   if (yydebug)
  496.     fprintf(stderr, "Starting parse\n");
  497. #endif
  498.  
  499.   yystate = 0;
  500.   yyerrstatus = 0;
  501.   yynerr = 0;
  502.   yychar = YYEMPTY;        /* Cause a token to be read.  */
  503.  
  504.   /* Initialize stack pointers.
  505.      Waste one element of value and location stack
  506.      so that they stay on the same level as the state stack.  */
  507.  
  508.   yyssp = yyss - 1;
  509.   yyvsp = yyvs;
  510.   yylsp = yyls;
  511.  
  512. /* Push a new state, which is found in  yystate  .  */
  513. /* In all cases, when you get here, the value and location stacks
  514.    have just been pushed. so pushing a state here evens the stacks.  */
  515. yynewstate:
  516.  
  517.   *++yyssp = yystate;
  518.  
  519.   if (yyssp >= yyss + yymaxdepth - 1)
  520.     {
  521.       /* Give user a chance to reallocate the stack */
  522.       /* Use copies of these so that the &'s don't force the real ones into memory. */
  523.       YYSTYPE *yyvs1 = yyvs;
  524.       YYLTYPE *yyls1 = yyls;
  525.       short *yyss1 = yyss;
  526.  
  527.       /* Get the current used size of the three stacks, in elements.  */
  528.       int size = yyssp - yyss + 1;
  529.  
  530. #ifdef yyoverflow
  531.       /* Each stack pointer address is followed by the size of
  532.      the data in use in that stack, in bytes.  */
  533.       yyoverflow("parser stack overflow",
  534.          &yyss1, size * sizeof (*yyssp),
  535.          &yyvs1, size * sizeof (*yyvsp),
  536.          &yyls1, size * sizeof (*yylsp),
  537.          &yymaxdepth);
  538.  
  539.       yyss = yyss1; yyvs = yyvs1; yyls = yyls1;
  540. #else /* no yyoverflow */
  541.       /* Extend the stack our own way.  */
  542.       if (yymaxdepth >= YYMAXLIMIT)
  543.     yyerror("parser stack overflow");
  544.       yymaxdepth *= 2;
  545.       if (yymaxdepth > YYMAXLIMIT)
  546.     yymaxdepth = YYMAXLIMIT;
  547.       yyss = (short *) alloca (yymaxdepth * sizeof (*yyssp));
  548.       bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp));
  549.       yyvs = (YYSTYPE *) alloca (yymaxdepth * sizeof (*yyvsp));
  550.       bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp));
  551. #ifdef YYLSP_NEEDED
  552.       yyls = (YYLTYPE *) alloca (yymaxdepth * sizeof (*yylsp));
  553.       bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp));
  554. #endif
  555. #endif /* no yyoverflow */
  556.  
  557.       yyssp = yyss + size - 1;
  558.       yyvsp = yyvs + size - 1;
  559. #ifdef YYLSP_NEEDED
  560.       yylsp = yyls + size - 1;
  561. #endif
  562.  
  563. #ifdef YYDEBUG
  564.       if (yydebug)
  565.     fprintf(stderr, "Stack size increased to %d\n", yymaxdepth);
  566. #endif
  567.  
  568.       if (yyssp >= yyss + yymaxdepth - 1)
  569.     YYABORT;
  570.     }
  571.  
  572. #ifdef YYDEBUG
  573.   if (yydebug)
  574.     fprintf(stderr, "Entering state %d\n", yystate);
  575. #endif
  576.  
  577. /* Do appropriate processing given the current state.  */
  578. /* Read a lookahead token if we need one and don't already have one.  */
  579. yyresume:
  580.  
  581.   /* First try to decide what to do without reference to lookahead token.  */
  582.  
  583.   yyn = yypact[yystate];
  584.   if (yyn == YYFLAG)
  585.     goto yydefault;
  586.  
  587.   /* Not known => get a lookahead token if don't already have one.  */
  588.  
  589.   /* yychar is either YYEMPTY or YYEOF
  590.      or a valid token in external form.  */
  591.  
  592.   if (yychar == YYEMPTY)
  593.     {
  594. #ifdef YYDEBUG
  595.       if (yydebug)
  596.     fprintf(stderr, "Reading a token: ");
  597. #endif
  598.       yychar = YYLEX;
  599.     }
  600.  
  601.   /* Convert token to internal form (in yychar1) for indexing tables with */
  602.  
  603.   if (yychar <= 0)        /* This means end of input. */
  604.     {
  605.       yychar1 = 0;
  606.       yychar = YYEOF;        /* Don't call YYLEX any more */
  607.  
  608. #ifdef YYDEBUG
  609.       if (yydebug)
  610.     fprintf(stderr, "Now at end of input.\n");
  611. #endif
  612.     }
  613.   else
  614.     {
  615.       yychar1 = YYTRANSLATE(yychar);
  616.  
  617. #ifdef YYDEBUG
  618.       if (yydebug)
  619.     fprintf(stderr, "Next token is %d (%s)\n", yychar, yytname[yychar1]);
  620. #endif
  621.     }
  622.  
  623.   yyn += yychar1;
  624.   if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
  625.     goto yydefault;
  626.  
  627.   yyn = yytable[yyn];
  628.  
  629.   /* yyn is what to do for this token type in this state.
  630.      Negative => reduce, -yyn is rule number.
  631.      Positive => shift, yyn is new state.
  632.        New state is final state => don't bother to shift,
  633.        just return success.
  634.      0, or most negative number => error.  */
  635.  
  636.   if (yyn < 0)
  637.     {
  638.       if (yyn == YYFLAG)
  639.     goto yyerrlab;
  640.       yyn = -yyn;
  641.       goto yyreduce;
  642.     }
  643.   else if (yyn == 0)
  644.     goto yyerrlab;
  645.  
  646.   if (yyn == YYFINAL)
  647.     YYACCEPT;
  648.  
  649.   /* Shift the lookahead token.  */
  650.  
  651. #ifdef YYDEBUG
  652.   if (yydebug)
  653.     fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
  654. #endif
  655.  
  656.   /* Discard the token being shifted unless it is eof.  */
  657.   if (yychar != YYEOF)
  658.     yychar = YYEMPTY;
  659.  
  660.   *++yyvsp = yylval;
  661. #ifdef YYLSP_NEEDED
  662.   *++yylsp = yylloc;
  663. #endif
  664.  
  665.   /* count tokens shifted since error; after three, turn off error status.  */
  666.   if (yyerrstatus) yyerrstatus--;
  667.  
  668.   yystate = yyn;
  669.   goto yynewstate;
  670.  
  671. /* Do the default action for the current state.  */
  672. yydefault:
  673.  
  674.   yyn = yydefact[yystate];
  675.   if (yyn == 0)
  676.     goto yyerrlab;
  677.  
  678. /* Do a reduction.  yyn is the number of a rule to reduce with.  */
  679. yyreduce:
  680.   yylen = yyr2[yyn];
  681.   yyval = yyvsp[1-yylen]; /* implement default value of the action */
  682.  
  683. #ifdef YYDEBUG
  684.   if (yydebug)
  685.     {
  686.       if (yylen == 1)
  687.     fprintf (stderr, "Reducing 1 value via line %d, ",
  688.          yyrline[yyn]);
  689.       else
  690.     fprintf (stderr, "Reducing %d values via line %d, ",
  691.          yylen, yyrline[yyn]);
  692.     }
  693. #endif
  694.  
  695.  
  696.   switch (yyn) {
  697.  
  698. case 3:
  699. #line 152 "getdate.y"
  700. {
  701.         yyHaveTime++;
  702.     ;
  703.     break;}
  704. case 4:
  705. #line 155 "getdate.y"
  706. {
  707.         yyHaveZone++;
  708.     ;
  709.     break;}
  710. case 5:
  711. #line 158 "getdate.y"
  712. {
  713.         yyHaveDate++;
  714.     ;
  715.     break;}
  716. case 6:
  717. #line 161 "getdate.y"
  718. {
  719.         yyHaveDay++;
  720.     ;
  721.     break;}
  722. case 7:
  723. #line 164 "getdate.y"
  724. {
  725.         yyHaveRel++;
  726.     ;
  727.     break;}
  728. case 9:
  729. #line 170 "getdate.y"
  730. {
  731.         yyHour = yyvsp[-1].Number;
  732.         yyMinutes = 0;
  733.         yySeconds = 0;
  734.         yyMeridian = yyvsp[0].Meridian;
  735.     ;
  736.     break;}
  737. case 10:
  738. #line 176 "getdate.y"
  739. {
  740.         yyHour = yyvsp[-3].Number;
  741.         yyMinutes = yyvsp[-1].Number;
  742.         yySeconds = 0;
  743.         yyMeridian = yyvsp[0].Meridian;
  744.     ;
  745.     break;}
  746. case 11:
  747. #line 182 "getdate.y"
  748. {
  749.         yyHour = yyvsp[-3].Number;
  750.         yyMinutes = yyvsp[-1].Number;
  751.         yyMeridian = MER24;
  752.         yyDSTmode = DSToff;
  753.         yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
  754.     ;
  755.     break;}
  756. case 12:
  757. #line 189 "getdate.y"
  758. {
  759.         yyHour = yyvsp[-5].Number;
  760.         yyMinutes = yyvsp[-3].Number;
  761.         yySeconds = yyvsp[-1].Number;
  762.         yyMeridian = yyvsp[0].Meridian;
  763.     ;
  764.     break;}
  765. case 13:
  766. #line 195 "getdate.y"
  767. {
  768.         yyHour = yyvsp[-5].Number;
  769.         yyMinutes = yyvsp[-3].Number;
  770.         yySeconds = yyvsp[-1].Number;
  771.         yyMeridian = MER24;
  772.         yyDSTmode = DSToff;
  773.         yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
  774.     ;
  775.     break;}
  776. case 14:
  777. #line 205 "getdate.y"
  778. {
  779.         yyTimezone = yyvsp[0].Number;
  780.         yyDSTmode = DSToff;
  781.     ;
  782.     break;}
  783. case 15:
  784. #line 209 "getdate.y"
  785. {
  786.         yyTimezone = yyvsp[0].Number;
  787.         yyDSTmode = DSTon;
  788.     ;
  789.     break;}
  790. case 16:
  791. #line 214 "getdate.y"
  792. {
  793.         yyTimezone = yyvsp[-1].Number;
  794.         yyDSTmode = DSTon;
  795.     ;
  796.     break;}
  797. case 17:
  798. #line 220 "getdate.y"
  799. {
  800.         yyDayOrdinal = 1;
  801.         yyDayNumber = yyvsp[0].Number;
  802.     ;
  803.     break;}
  804. case 18:
  805. #line 224 "getdate.y"
  806. {
  807.         yyDayOrdinal = 1;
  808.         yyDayNumber = yyvsp[-1].Number;
  809.     ;
  810.     break;}
  811. case 19:
  812. #line 228 "getdate.y"
  813. {
  814.         yyDayOrdinal = yyvsp[-1].Number;
  815.         yyDayNumber = yyvsp[0].Number;
  816.     ;
  817.     break;}
  818. case 20:
  819. #line 234 "getdate.y"
  820. {
  821.         yyMonth = yyvsp[-2].Number;
  822.         yyDay = yyvsp[0].Number;
  823.     ;
  824.     break;}
  825. case 21:
  826. #line 238 "getdate.y"
  827. {
  828.         yyMonth = yyvsp[-4].Number;
  829.         yyDay = yyvsp[-2].Number;
  830.         yyYear = yyvsp[0].Number;
  831.     ;
  832.     break;}
  833. case 22:
  834. #line 243 "getdate.y"
  835. {
  836.         yyMonth = yyvsp[-1].Number;
  837.         yyDay = yyvsp[0].Number;
  838.     ;
  839.     break;}
  840. case 23:
  841. #line 247 "getdate.y"
  842. {
  843.         yyMonth = yyvsp[-3].Number;
  844.         yyDay = yyvsp[-2].Number;
  845.         yyYear = yyvsp[0].Number;
  846.     ;
  847.     break;}
  848. case 24:
  849. #line 252 "getdate.y"
  850. {
  851.         yyMonth = yyvsp[0].Number;
  852.         yyDay = yyvsp[-1].Number;
  853.     ;
  854.     break;}
  855. case 25:
  856. #line 256 "getdate.y"
  857. {
  858.         yyMonth = yyvsp[-1].Number;
  859.         yyDay = yyvsp[-2].Number;
  860.         yyYear = yyvsp[0].Number;
  861.     ;
  862.     break;}
  863. case 26:
  864. #line 263 "getdate.y"
  865. {
  866.         yyRelSeconds = -yyRelSeconds;
  867.         yyRelMonth = -yyRelMonth;
  868.     ;
  869.     break;}
  870. case 28:
  871. #line 270 "getdate.y"
  872. {
  873.         yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
  874.     ;
  875.     break;}
  876. case 29:
  877. #line 273 "getdate.y"
  878. {
  879.         yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
  880.     ;
  881.     break;}
  882. case 30:
  883. #line 276 "getdate.y"
  884. {
  885.         yyRelSeconds += yyvsp[0].Number * 60L;
  886.     ;
  887.     break;}
  888. case 31:
  889. #line 279 "getdate.y"
  890. {
  891.         yyRelSeconds += yyvsp[-1].Number;
  892.     ;
  893.     break;}
  894. case 32:
  895. #line 282 "getdate.y"
  896. {
  897.         yyRelSeconds += yyvsp[-1].Number;
  898.     ;
  899.     break;}
  900. case 33:
  901. #line 285 "getdate.y"
  902. {
  903.         yyRelSeconds++;
  904.     ;
  905.     break;}
  906. case 34:
  907. #line 288 "getdate.y"
  908. {
  909.         yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
  910.     ;
  911.     break;}
  912. case 35:
  913. #line 291 "getdate.y"
  914. {
  915.         yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
  916.     ;
  917.     break;}
  918. case 36:
  919. #line 294 "getdate.y"
  920. {
  921.         yyRelMonth += yyvsp[0].Number;
  922.     ;
  923.     break;}
  924. case 37:
  925. #line 299 "getdate.y"
  926. {
  927.         if (yyHaveTime && yyHaveDate && !yyHaveRel)
  928.         yyYear = yyvsp[0].Number;
  929.         else {
  930.         if(yyvsp[0].Number>10000) {
  931.             time_t date_part;
  932.  
  933.             date_part= yyvsp[0].Number/10000;
  934.             yyHaveDate++;
  935.             yyDay= (date_part)%100;
  936.             yyMonth= (date_part/100)%100;
  937.             yyYear = date_part/10000;
  938.         } 
  939.             yyHaveTime++;
  940.         if (yyvsp[0].Number < 100) {
  941.             yyHour = yyvsp[0].Number;
  942.             yyMinutes = 0;
  943.         }
  944.         else {
  945.             yyHour = yyvsp[0].Number / 100;
  946.             yyMinutes = yyvsp[0].Number % 100;
  947.         }
  948.         yySeconds = 0;
  949.         yyMeridian = MER24;
  950.         }
  951.     ;
  952.     break;}
  953. case 38:
  954. #line 327 "getdate.y"
  955. {
  956.         yyval.Meridian = MER24;
  957.     ;
  958.     break;}
  959. case 39:
  960. #line 330 "getdate.y"
  961. {
  962.         yyval.Meridian = yyvsp[0].Meridian;
  963.     ;
  964.     break;}
  965. }
  966.    /* the action file gets copied in in place of this dollarsign */
  967. #line 409 "bison.simple"
  968.  
  969.   yyvsp -= yylen;
  970.   yyssp -= yylen;
  971. #ifdef YYLSP_NEEDED
  972.   yylsp -= yylen;
  973. #endif
  974.  
  975. #ifdef YYDEBUG
  976.   if (yydebug)
  977.     {
  978.       short *ssp1 = yyss - 1;
  979.       fprintf (stderr, "state stack now");
  980.       while (ssp1 != yyssp)
  981.     fprintf (stderr, " %d", *++ssp1);
  982.       fprintf (stderr, "\n");
  983.     }
  984. #endif
  985.  
  986.   *++yyvsp = yyval;
  987.  
  988. #ifdef YYLSP_NEEDED
  989.   yylsp++;
  990.   if (yylen == 0)
  991.     {
  992.       yylsp->first_line = yylloc.first_line;
  993.       yylsp->first_column = yylloc.first_column;
  994.       yylsp->last_line = (yylsp-1)->last_line;
  995.       yylsp->last_column = (yylsp-1)->last_column;
  996.       yylsp->text = 0;
  997.     }
  998.   else
  999.     {
  1000.       yylsp->last_line = (yylsp+yylen-1)->last_line;
  1001.       yylsp->last_column = (yylsp+yylen-1)->last_column;
  1002.     }
  1003. #endif
  1004.  
  1005.   /* Now "shift" the result of the reduction.
  1006.      Determine what state that goes to,
  1007.      based on the state we popped back to
  1008.      and the rule number reduced by.  */
  1009.  
  1010.   yyn = yyr1[yyn];
  1011.  
  1012.   yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
  1013.   if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
  1014.     yystate = yytable[yystate];
  1015.   else
  1016.     yystate = yydefgoto[yyn - YYNTBASE];
  1017.  
  1018.   goto yynewstate;
  1019.  
  1020. yyerrlab:   /* here on detecting error */
  1021.  
  1022.   if (! yyerrstatus)
  1023.     /* If not already recovering from an error, report this error.  */
  1024.     {
  1025.       ++yynerr;
  1026.       yyerror("parse error");
  1027.     }
  1028.  
  1029.   if (yyerrstatus == 3)
  1030.     {
  1031.       /* if just tried and failed to reuse lookahead token after an error, discard it.  */
  1032.  
  1033.       /* return failure if at end of input */
  1034.       if (yychar == YYEOF)
  1035.     YYABORT;
  1036.  
  1037. #ifdef YYDEBUG
  1038.       if (yydebug)
  1039.     fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
  1040. #endif
  1041.  
  1042.       yychar = YYEMPTY;
  1043.     }
  1044.  
  1045.   /* Else will try to reuse lookahead token
  1046.      after shifting the error token.  */
  1047.  
  1048.   yyerrstatus = 3;        /* Each real token shifted decrements this */
  1049.  
  1050.   goto yyerrhandle;
  1051.  
  1052. yyerrdefault:  /* current state does not do anything special for the error token. */
  1053.  
  1054. #if 0
  1055.   /* This is wrong; only states that explicitly want error tokens
  1056.      should shift them.  */
  1057.   yyn = yydefact[yystate];  /* If its default is to accept any token, ok.  Otherwise pop it.*/
  1058.   if (yyn) goto yydefault;
  1059. #endif
  1060.  
  1061. yyerrpop:   /* pop the current state because it cannot handle the error token */
  1062.  
  1063.   if (yyssp == yyss) YYABORT;
  1064.   yyvsp--;
  1065.   yystate = *--yyssp;
  1066. #ifdef YYLSP_NEEDED
  1067.   yylsp--;
  1068. #endif
  1069.  
  1070. #ifdef YYDEBUG
  1071.   if (yydebug)
  1072.     {
  1073.       short *ssp1 = yyss - 1;
  1074.       fprintf (stderr, "Error: state stack now");
  1075.       while (ssp1 != yyssp)
  1076.     fprintf (stderr, " %d", *++ssp1);
  1077.       fprintf (stderr, "\n");
  1078.     }
  1079. #endif
  1080.  
  1081. yyerrhandle:
  1082.  
  1083.   yyn = yypact[yystate];
  1084.   if (yyn == YYFLAG)
  1085.     goto yyerrdefault;
  1086.  
  1087.   yyn += YYTERROR;
  1088.   if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
  1089.     goto yyerrdefault;
  1090.  
  1091.   yyn = yytable[yyn];
  1092.   if (yyn < 0)
  1093.     {
  1094.       if (yyn == YYFLAG)
  1095.     goto yyerrpop;
  1096.       yyn = -yyn;
  1097.       goto yyreduce;
  1098.     }
  1099.   else if (yyn == 0)
  1100.     goto yyerrpop;
  1101.  
  1102.   if (yyn == YYFINAL)
  1103.     YYACCEPT;
  1104.  
  1105. #ifdef YYDEBUG
  1106.   if (yydebug)
  1107.     fprintf(stderr, "Shifting error token, ");
  1108. #endif
  1109.  
  1110.   *++yyvsp = yylval;
  1111. #ifdef YYLSP_NEEDED
  1112.   *++yylsp = yylloc;
  1113. #endif
  1114.  
  1115.   yystate = yyn;
  1116.   goto yynewstate;
  1117. }
  1118. #line 335 "getdate.y"
  1119.  
  1120.  
  1121. /* Month and day table. */
  1122. static TABLE    MonthDayTable[] = {
  1123.     { "january",    tMONTH,  1 },
  1124.     { "february",    tMONTH,  2 },
  1125.     { "march",        tMONTH,  3 },
  1126.     { "april",        tMONTH,  4 },
  1127.     { "may",        tMONTH,  5 },
  1128.     { "june",        tMONTH,  6 },
  1129.     { "july",        tMONTH,  7 },
  1130.     { "august",        tMONTH,  8 },
  1131.     { "september",    tMONTH,  9 },
  1132.     { "sept",        tMONTH,  9 },
  1133.     { "october",    tMONTH, 10 },
  1134.     { "november",    tMONTH, 11 },
  1135.     { "december",    tMONTH, 12 },
  1136.     { "sunday",        tDAY, 0 },
  1137.     { "monday",        tDAY, 1 },
  1138.     { "tuesday",    tDAY, 2 },
  1139.     { "tues",        tDAY, 2 },
  1140.     { "wednesday",    tDAY, 3 },
  1141.     { "wednes",        tDAY, 3 },
  1142.     { "thursday",    tDAY, 4 },
  1143.     { "thur",        tDAY, 4 },
  1144.     { "thurs",        tDAY, 4 },
  1145.     { "friday",        tDAY, 5 },
  1146.     { "saturday",    tDAY, 6 },
  1147.     { NULL }
  1148. };
  1149.  
  1150. /* Time units table. */
  1151. static TABLE    UnitsTable[] = {
  1152.     { "year",        tMONTH_UNIT,    12 },
  1153.     { "month",        tMONTH_UNIT,    1 },
  1154.     { "fortnight",    tMINUTE_UNIT,    14 * 24 * 60 },
  1155.     { "week",        tMINUTE_UNIT,    7 * 24 * 60 },
  1156.     { "day",        tMINUTE_UNIT,    1 * 24 * 60 },
  1157.     { "hour",        tMINUTE_UNIT,    60 },
  1158.     { "minute",        tMINUTE_UNIT,    1 },
  1159.     { "min",        tMINUTE_UNIT,    1 },
  1160.     { "second",        tSEC_UNIT,    1 },
  1161.     { "sec",        tSEC_UNIT,    1 },
  1162.     { NULL }
  1163. };
  1164.  
  1165. /* Assorted relative-time words. */
  1166. static TABLE    OtherTable[] = {
  1167.     { "tomorrow",    tMINUTE_UNIT,    1 * 24 * 60 },
  1168.     { "yesterday",    tMINUTE_UNIT,    -1 * 24 * 60 },
  1169.     { "today",        tMINUTE_UNIT,    0 },
  1170.     { "now",        tMINUTE_UNIT,    0 },
  1171.     { "last",        tUNUMBER,    -1 },
  1172.     { "this",        tMINUTE_UNIT,    0 },
  1173.     { "next",        tUNUMBER,    2 },
  1174.     { "first",        tUNUMBER,    1 },
  1175. /*  { "second",        tUNUMBER,    2 }, */
  1176.     { "third",        tUNUMBER,    3 },
  1177.     { "fourth",        tUNUMBER,    4 },
  1178.     { "fifth",        tUNUMBER,    5 },
  1179.     { "sixth",        tUNUMBER,    6 },
  1180.     { "seventh",    tUNUMBER,    7 },
  1181.     { "eighth",        tUNUMBER,    8 },
  1182.     { "ninth",        tUNUMBER,    9 },
  1183.     { "tenth",        tUNUMBER,    10 },
  1184.     { "eleventh",    tUNUMBER,    11 },
  1185.     { "twelfth",    tUNUMBER,    12 },
  1186.     { "ago",        tAGO,    1 },
  1187.     { NULL }
  1188. };
  1189.  
  1190. /* The timezone table. */
  1191. /* Some of these are commented out because a time_t can't store a float. */
  1192. static TABLE    TimezoneTable[] = {
  1193.     { "gmt",    tZONE,     HOUR( 0) },    /* Greenwich Mean */
  1194.     { "ut",    tZONE,     HOUR( 0) },    /* Universal (Coordinated) */
  1195.     { "utc",    tZONE,     HOUR( 0) },
  1196.     { "wet",    tZONE,     HOUR( 0) },    /* Western European */
  1197.     { "bst",    tDAYZONE,  HOUR( 0) },    /* British Summer */
  1198.     { "wat",    tZONE,     HOUR( 1) },    /* West Africa */
  1199.     { "at",    tZONE,     HOUR( 2) },    /* Azores */
  1200. #if    0
  1201.     /* For completeness.  BST is also British Summer, and GST is
  1202.      * also Guam Standard. */
  1203.     { "bst",    tZONE,     HOUR( 3) },    /* Brazil Standard */
  1204.     { "gst",    tZONE,     HOUR( 3) },    /* Greenland Standard */
  1205. #endif
  1206. #if 0
  1207.     { "nft",    tZONE,     HOUR(3.5) },    /* Newfoundland */
  1208.     { "nst",    tZONE,     HOUR(3.5) },    /* Newfoundland Standard */
  1209.     { "ndt",    tDAYZONE,  HOUR(3.5) },    /* Newfoundland Daylight */
  1210. #endif
  1211.     { "ast",    tZONE,     HOUR( 4) },    /* Atlantic Standard */
  1212.     { "adt",    tDAYZONE,  HOUR( 4) },    /* Atlantic Daylight */
  1213.     { "est",    tZONE,     HOUR( 5) },    /* Eastern Standard */
  1214.     { "edt",    tDAYZONE,  HOUR( 5) },    /* Eastern Daylight */
  1215.     { "cst",    tZONE,     HOUR( 6) },    /* Central Standard */
  1216.     { "cdt",    tDAYZONE,  HOUR( 6) },    /* Central Daylight */
  1217.     { "mst",    tZONE,     HOUR( 7) },    /* Mountain Standard */
  1218.     { "mdt",    tDAYZONE,  HOUR( 7) },    /* Mountain Daylight */
  1219.     { "pst",    tZONE,     HOUR( 8) },    /* Pacific Standard */
  1220.     { "pdt",    tDAYZONE,  HOUR( 8) },    /* Pacific Daylight */
  1221.     { "yst",    tZONE,     HOUR( 9) },    /* Yukon Standard */
  1222.     { "ydt",    tDAYZONE,  HOUR( 9) },    /* Yukon Daylight */
  1223.     { "hst",    tZONE,     HOUR(10) },    /* Hawaii Standard */
  1224.     { "hdt",    tDAYZONE,  HOUR(10) },    /* Hawaii Daylight */
  1225.     { "cat",    tZONE,     HOUR(10) },    /* Central Alaska */
  1226.     { "ahst",    tZONE,     HOUR(10) },    /* Alaska-Hawaii Standard */
  1227.     { "nt",    tZONE,     HOUR(11) },    /* Nome */
  1228.     { "idlw",    tZONE,     HOUR(12) },    /* International Date Line West */
  1229.     { "cet",    tZONE,     -HOUR(1) },    /* Central European */
  1230.     { "met",    tZONE,     -HOUR(1) },    /* Middle European */
  1231.     { "mewt",    tZONE,     -HOUR(1) },    /* Middle European Winter */
  1232.     { "mest",    tDAYZONE,  -HOUR(1) },    /* Middle European Summer */
  1233.     { "swt",    tZONE,     -HOUR(1) },    /* Swedish Winter */
  1234.     { "sst",    tDAYZONE,  -HOUR(1) },    /* Swedish Summer */
  1235.     { "fwt",    tZONE,     -HOUR(1) },    /* French Winter */
  1236.     { "fst",    tDAYZONE,  -HOUR(1) },    /* French Summer */
  1237.     { "eet",    tZONE,     -HOUR(2) },    /* Eastern Europe, USSR Zone 1 */
  1238.     { "bt",    tZONE,     -HOUR(3) },    /* Baghdad, USSR Zone 2 */
  1239. #if 0
  1240.     { "it",    tZONE,     -HOUR(3.5) },/* Iran */
  1241. #endif
  1242.     { "zp4",    tZONE,     -HOUR(4) },    /* USSR Zone 3 */
  1243.     { "zp5",    tZONE,     -HOUR(5) },    /* USSR Zone 4 */
  1244. #if 0
  1245.     { "ist",    tZONE,     -HOUR(5.5) },/* Indian Standard */
  1246. #endif
  1247.     { "zp6",    tZONE,     -HOUR(6) },    /* USSR Zone 5 */
  1248. #if    0
  1249.     /* For completeness.  NST is also Newfoundland Stanard, nad SST is
  1250.      * also Swedish Summer. */
  1251.     { "nst",    tZONE,     -HOUR(6.5) },/* North Sumatra */
  1252.     { "sst",    tZONE,     -HOUR(7) },    /* South Sumatra, USSR Zone 6 */
  1253. #endif    /* 0 */
  1254.     { "wast",    tZONE,     -HOUR(7) },    /* West Australian Standard */
  1255.     { "wadt",    tDAYZONE,  -HOUR(7) },    /* West Australian Daylight */
  1256. #if 0
  1257.     { "jt",    tZONE,     -HOUR(7.5) },/* Java (3pm in Cronusland!) */
  1258. #endif
  1259.     { "cct",    tZONE,     -HOUR(8) },    /* China Coast, USSR Zone 7 */
  1260.     { "jst",    tZONE,     -HOUR(9) },    /* Japan Standard, USSR Zone 8 */
  1261. #if 0
  1262.     { "cast",    tZONE,     -HOUR(9.5) },/* Central Australian Standard */
  1263.     { "cadt",    tDAYZONE,  -HOUR(9.5) },/* Central Australian Daylight */
  1264. #endif
  1265.     { "east",    tZONE,     -HOUR(10) },    /* Eastern Australian Standard */
  1266.     { "eadt",    tDAYZONE,  -HOUR(10) },    /* Eastern Australian Daylight */
  1267.     { "gst",    tZONE,     -HOUR(10) },    /* Guam Standard, USSR Zone 9 */
  1268.     { "nzt",    tZONE,     -HOUR(12) },    /* New Zealand */
  1269.     { "nzst",    tZONE,     -HOUR(12) },    /* New Zealand Standard */
  1270.     { "nzdt",    tDAYZONE,  -HOUR(12) },    /* New Zealand Daylight */
  1271.     { "idle",    tZONE,     -HOUR(12) },    /* International Date Line East */
  1272.     {  NULL  }
  1273. };
  1274.  
  1275. /* Military timezone table. */
  1276. static TABLE    MilitaryTable[] = {
  1277.     { "a",    tZONE,    HOUR(  1) },
  1278.     { "b",    tZONE,    HOUR(  2) },
  1279.     { "c",    tZONE,    HOUR(  3) },
  1280.     { "d",    tZONE,    HOUR(  4) },
  1281.     { "e",    tZONE,    HOUR(  5) },
  1282.     { "f",    tZONE,    HOUR(  6) },
  1283.     { "g",    tZONE,    HOUR(  7) },
  1284.     { "h",    tZONE,    HOUR(  8) },
  1285.     { "i",    tZONE,    HOUR(  9) },
  1286.     { "k",    tZONE,    HOUR( 10) },
  1287.     { "l",    tZONE,    HOUR( 11) },
  1288.     { "m",    tZONE,    HOUR( 12) },
  1289.     { "n",    tZONE,    HOUR(- 1) },
  1290.     { "o",    tZONE,    HOUR(- 2) },
  1291.     { "p",    tZONE,    HOUR(- 3) },
  1292.     { "q",    tZONE,    HOUR(- 4) },
  1293.     { "r",    tZONE,    HOUR(- 5) },
  1294.     { "s",    tZONE,    HOUR(- 6) },
  1295.     { "t",    tZONE,    HOUR(- 7) },
  1296.     { "u",    tZONE,    HOUR(- 8) },
  1297.     { "v",    tZONE,    HOUR(- 9) },
  1298.     { "w",    tZONE,    HOUR(-10) },
  1299.     { "x",    tZONE,    HOUR(-11) },
  1300.     { "y",    tZONE,    HOUR(-12) },
  1301.     { "z",    tZONE,    HOUR(  0) },
  1302.     { NULL }
  1303. };
  1304.  
  1305.  
  1306.  
  1307.  
  1308. /* ARGSUSED */
  1309. int
  1310. yyerror(s)
  1311.     char    *s;
  1312. {
  1313.   return 0;
  1314. }
  1315.  
  1316.  
  1317. static time_t
  1318. ToSeconds(Hours, Minutes, Seconds, Meridian)
  1319.     time_t    Hours;
  1320.     time_t    Minutes;
  1321.     time_t    Seconds;
  1322.     MERIDIAN    Meridian;
  1323. {
  1324.     if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59)
  1325.     return -1;
  1326.     switch (Meridian) {
  1327.     case MER24:
  1328.     if (Hours < 0 || Hours > 23)
  1329.         return -1;
  1330.     return (Hours * 60L + Minutes) * 60L + Seconds;
  1331.     case MERam:
  1332.     if (Hours < 1 || Hours > 12)
  1333.         return -1;
  1334.     return (Hours * 60L + Minutes) * 60L + Seconds;
  1335.     case MERpm:
  1336.     if (Hours < 1 || Hours > 12)
  1337.         return -1;
  1338.     return ((Hours + 12) * 60L + Minutes) * 60L + Seconds;
  1339.     }
  1340.     /* NOTREACHED */
  1341. }
  1342.  
  1343.  
  1344. static time_t
  1345. Convert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, DSTmode)
  1346.     time_t    Month;
  1347.     time_t    Day;
  1348.     time_t    Year;
  1349.     time_t    Hours;
  1350.     time_t    Minutes;
  1351.     time_t    Seconds;
  1352.     MERIDIAN    Meridian;
  1353.     DSTMODE    DSTmode;
  1354. {
  1355.     static int    DaysInMonth[12] = {
  1356.     31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  1357.     };
  1358.     time_t    tod;
  1359.     time_t    Julian;
  1360.     int        i;
  1361.  
  1362.     if (Year < 0)
  1363.     Year = -Year;
  1364.     if (Year < 100)
  1365.     Year += 1900;
  1366.     DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0)
  1367.             ? 29 : 28;
  1368.     if (Year < EPOCH || Year > 1999
  1369.      || Month < 1 || Month > 12
  1370.      /* Lint fluff:  "conversion from long may lose accuracy" */
  1371.      || Day < 1 || Day > DaysInMonth[(int)--Month])
  1372.     return -1;
  1373.  
  1374.     for (Julian = Day - 1, i = 0; i < Month; i++)
  1375.     Julian += DaysInMonth[i];
  1376.     for (i = EPOCH; i < Year; i++)
  1377.     Julian += 365 + (i % 4 == 0);
  1378.     Julian *= SECSPERDAY;
  1379.     Julian += yyTimezone * 60L;
  1380.     if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
  1381.     return -1;
  1382.     Julian += tod;
  1383.     if (DSTmode == DSTon
  1384.      || (DSTmode == DSTmaybe && localtime(&Julian)->tm_isdst))
  1385.     Julian -= 60 * 60;
  1386.     return Julian;
  1387. }
  1388.  
  1389.  
  1390. static time_t
  1391. DSTcorrect(Start, Future)
  1392.     time_t    Start;
  1393.     time_t    Future;
  1394. {
  1395.     time_t    StartDay;
  1396.     time_t    FutureDay;
  1397.  
  1398.     StartDay = (localtime(&Start)->tm_hour + 1) % 24;
  1399.     FutureDay = (localtime(&Future)->tm_hour + 1) % 24;
  1400.     return (Future - Start) + (StartDay - FutureDay) * 60L * 60L;
  1401. }
  1402.  
  1403.  
  1404. static time_t
  1405. RelativeDate(Start, DayOrdinal, DayNumber)
  1406.     time_t    Start;
  1407.     time_t    DayOrdinal;
  1408.     time_t    DayNumber;
  1409. {
  1410.     struct tm    *tm;
  1411.     time_t    now;
  1412.  
  1413.     now = Start;
  1414.     tm = localtime(&now);
  1415.     now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7);
  1416.     now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
  1417.     return DSTcorrect(Start, now);
  1418. }
  1419.  
  1420.  
  1421. static time_t
  1422. RelativeMonth(Start, RelMonth)
  1423.     time_t    Start;
  1424.     time_t    RelMonth;
  1425. {
  1426.     struct tm    *tm;
  1427.     time_t    Month;
  1428.     time_t    Year;
  1429.  
  1430.     if (RelMonth == 0)
  1431.     return 0;
  1432.     tm = localtime(&Start);
  1433.     Month = 12 * tm->tm_year + tm->tm_mon + RelMonth;
  1434.     Year = Month / 12;
  1435.     Month = Month % 12 + 1;
  1436.     return DSTcorrect(Start,
  1437.         Convert(Month, (time_t)tm->tm_mday, Year,
  1438.         (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec,
  1439.         MER24, DSTmaybe));
  1440. }
  1441.  
  1442.  
  1443. static int
  1444. LookupWord(buff)
  1445.     char        *buff;
  1446. {
  1447.     register char    *p;
  1448.     register char    *q;
  1449.     register TABLE    *tp;
  1450.     int            i;
  1451.     int            abbrev;
  1452.  
  1453.     /* Make it lowercase. */
  1454.     for (p = buff; *p; p++)
  1455.     if (isupper(*p))
  1456.         *p = tolower(*p);
  1457.  
  1458.     if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) {
  1459.     yylval.Meridian = MERam;
  1460.     return tMERIDIAN;
  1461.     }
  1462.     if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) {
  1463.     yylval.Meridian = MERpm;
  1464.     return tMERIDIAN;
  1465.     }
  1466.  
  1467.     /* See if we have an abbreviation for a month. */
  1468.     if (strlen(buff) == 3)
  1469.     abbrev = 1;
  1470.     else if (strlen(buff) == 4 && buff[3] == '.') {
  1471.     abbrev = 1;
  1472.     buff[3] = '\0';
  1473.     }
  1474.     else
  1475.     abbrev = 0;
  1476.  
  1477.     for (tp = MonthDayTable; tp->name; tp++) {
  1478.     if (abbrev) {
  1479.         if (strncmp(buff, tp->name, 3) == 0) {
  1480.         yylval.Number = tp->value;
  1481.         return tp->type;
  1482.         }
  1483.     }
  1484.     else if (strcmp(buff, tp->name) == 0) {
  1485.         yylval.Number = tp->value;
  1486.         return tp->type;
  1487.     }
  1488.     }
  1489.  
  1490.     for (tp = TimezoneTable; tp->name; tp++)
  1491.     if (strcmp(buff, tp->name) == 0) {
  1492.         yylval.Number = tp->value;
  1493.         return tp->type;
  1494.     }
  1495.  
  1496.     if (strcmp(buff, "dst") == 0) 
  1497.     return tDST;
  1498.  
  1499.     for (tp = UnitsTable; tp->name; tp++)
  1500.     if (strcmp(buff, tp->name) == 0) {
  1501.         yylval.Number = tp->value;
  1502.         return tp->type;
  1503.     }
  1504.  
  1505.     /* Strip off any plural and try the units table again. */
  1506.     i = strlen(buff) - 1;
  1507.     if (buff[i] == 's') {
  1508.     buff[i] = '\0';
  1509.     for (tp = UnitsTable; tp->name; tp++)
  1510.         if (strcmp(buff, tp->name) == 0) {
  1511.         yylval.Number = tp->value;
  1512.         return tp->type;
  1513.         }
  1514.     buff[i] = 's';        /* Put back for "this" in OtherTable. */
  1515.     }
  1516.  
  1517.     for (tp = OtherTable; tp->name; tp++)
  1518.     if (strcmp(buff, tp->name) == 0) {
  1519.         yylval.Number = tp->value;
  1520.         return tp->type;
  1521.     }
  1522.  
  1523.     /* Military timezones. */
  1524.     if (buff[1] == '\0' && isalpha(*buff)) {
  1525.     for (tp = MilitaryTable; tp->name; tp++)
  1526.         if (strcmp(buff, tp->name) == 0) {
  1527.         yylval.Number = tp->value;
  1528.         return tp->type;
  1529.         }
  1530.     }
  1531.  
  1532.     /* Drop out any periods and try the timezone table again. */
  1533.     for (i = 0, p = q = buff; *q; q++)
  1534.     if (*q != '.')
  1535.         *p++ = *q;
  1536.     else
  1537.         i++;
  1538.     *p = '\0';
  1539.     if (i)
  1540.     for (tp = TimezoneTable; tp->name; tp++)
  1541.         if (strcmp(buff, tp->name) == 0) {
  1542.         yylval.Number = tp->value;
  1543.         return tp->type;
  1544.         }
  1545.  
  1546.     return tID;
  1547. }
  1548.  
  1549.  
  1550. int
  1551. yylex()
  1552. {
  1553.     register char    c;
  1554.     register char    *p;
  1555.     char        buff[20];
  1556.     int            Count;
  1557.     int            sign;
  1558.  
  1559.     for ( ; ; ) {
  1560.     while (isspace(*yyInput))
  1561.         yyInput++;
  1562.  
  1563.     if (isdigit(c = *yyInput) || c == '-' || c == '+') {
  1564.         if (c == '-' || c == '+') {
  1565.         sign = c == '-' ? -1 : 1;
  1566.         if (!isdigit(*++yyInput))
  1567.             /* skip the '-' sign */
  1568.             continue;
  1569.         }
  1570.         else
  1571.         sign = 0;
  1572.         for (yylval.Number = 0; isdigit(c = *yyInput++); )
  1573.         yylval.Number = 10 * yylval.Number + c - '0';
  1574.         yyInput--;
  1575.         if (sign < 0)
  1576.         yylval.Number = -yylval.Number;
  1577.         return sign ? tSNUMBER : tUNUMBER;
  1578.     }
  1579.     if (isalpha(c)) {
  1580.         for (p = buff; isalpha(c = *yyInput++) || c == '.'; )
  1581.         if (p < &buff[sizeof buff - 1])
  1582.             *p++ = c;
  1583.         *p = '\0';
  1584.         yyInput--;
  1585.         return LookupWord(buff);
  1586.     }
  1587.     if (c != '(')
  1588.         return *yyInput++;
  1589.     Count = 0;
  1590.     do {
  1591.         c = *yyInput++;
  1592.         if (c == '\0')
  1593.         return c;
  1594.         if (c == '(')
  1595.         Count++;
  1596.         else if (c == ')')
  1597.         Count--;
  1598.     } while (Count > 0);
  1599.     }
  1600. }
  1601.  
  1602.  
  1603. time_t
  1604. get_date(p, now)
  1605.     char        *p;
  1606.     struct timeb    *now;
  1607. {
  1608.     struct tm        *tm;
  1609.     struct timeb    ftz;
  1610.     time_t        Start;
  1611.     time_t        tod;
  1612. #if    defined(FTIME_MISSING)
  1613.     extern time_t    timezone;
  1614. #endif    
  1615.  
  1616.     yyInput = p;
  1617.     if (now == NULL) {
  1618.     now = &ftz;
  1619. #if    defined(FTIME_MISSING)
  1620.     (void)time(&ftz.time);
  1621.     /* Set the timezone global. */
  1622.     tzset();
  1623.     ftz.timezone = (int) timezone / 60;
  1624. #else
  1625.     (void)ftime(&ftz);
  1626. #endif    /* defined(FTIME_MISSING) */
  1627.     }
  1628.  
  1629.     tm = localtime(&now->time);
  1630.     yyYear = tm->tm_year;
  1631.     yyMonth = tm->tm_mon + 1;
  1632.     yyDay = tm->tm_mday;
  1633.     yyTimezone = now->timezone;
  1634.     yyDSTmode = DSTmaybe;
  1635.     yyHour = 0;
  1636.     yyMinutes = 0;
  1637.     yySeconds = 0;
  1638.     yyMeridian = MER24;
  1639.     yyRelSeconds = 0;
  1640.     yyRelMonth = 0;
  1641.     yyHaveDate = 0;
  1642.     yyHaveDay = 0;
  1643.     yyHaveRel = 0;
  1644.     yyHaveTime = 0;
  1645.     yyHaveZone = 0;
  1646.  
  1647.     if (yyparse()
  1648.      || yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 || yyHaveDay > 1)
  1649.     return -1;
  1650.  
  1651.     if (yyHaveDate || yyHaveTime || yyHaveDay) {
  1652.     Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds,
  1653.             yyMeridian, yyDSTmode);
  1654.     if (Start < 0)
  1655.         return -1;
  1656.     }
  1657.     else {
  1658.     Start = now->time;
  1659.     if (!yyHaveRel)
  1660.         Start -= ((tm->tm_hour * 60L + tm->tm_min) * 60L) + tm->tm_sec;
  1661.     }
  1662.  
  1663.     Start += yyRelSeconds;
  1664.     Start += RelativeMonth(Start, yyRelMonth);
  1665.  
  1666.     if (yyHaveDay && !yyHaveDate) {
  1667.     tod = RelativeDate(Start, yyDayOrdinal, yyDayNumber);
  1668.     Start += tod;
  1669.     }
  1670.  
  1671.     /* Have to do *something* with a legitimate -1 so it's distinguishable
  1672.      * from the error return value.  (Alternately could set errno on error.) */
  1673.     return Start == -1 ? 0 : Start;
  1674. }
  1675.  
  1676.  
  1677. #if    defined(TEST)
  1678.  
  1679. /* ARGSUSED */
  1680. main(ac, av)
  1681.     int        ac;
  1682.     char    *av[];
  1683. {
  1684.     char    buff[128];
  1685.     time_t    d;
  1686.  
  1687.     (void)printf("Enter date, or blank line to exit.\n\t> ");
  1688.     (void)fflush(stdout);
  1689.     while (gets(buff) && buff[0]) {
  1690.     d = get_date(buff, (struct timeb *)NULL);
  1691.     if (d == -1)
  1692.         (void)printf("Bad format - couldn't convert.\n");
  1693.     else
  1694.         (void)printf("%s", ctime(&d));
  1695.     (void)printf("\t> ");
  1696.     (void)fflush(stdout);
  1697.     }
  1698.     exit(0);
  1699.     /* NOTREACHED */
  1700. }
  1701. #endif    /* defined(TEST) */
  1702.